package com.example.personblog.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.personblog.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper extends BaseMapper<User> {
//根据用户的id查询该用户id下所有的订单,一对多查询
//column → 数据库表的列名（SQL 结果的字段名）。property → Java 实体类的属性名。
//两者通过 @Result 建立映射关系，确保查询结果能正确赋值给实体对象的属性。@Result是给每一列进行赋值,从数据库中查询出来赋给类里
//如果数据库列名和实体属性名一致（如都叫id），可以省略该@Result配置（MyBatis 会自动映射同名的列和属性）
// 如果不一致（如数据库列是user_id，实体属性是userId），则必须通过@Result明确映射。
//一对多场景里UserMapper 是查询的 “主入口”，负责：
// 查询用户基本信息：执行 SQL select * from user，获取用户的 id、username、password 等基础字段。
// 触发关联查询订单：通过 MyBatis 的 @Many 注解，调用 OrderMapper 的方法，根据用户的 id 去查询该用户对应的所有订单，并将这些订单封装成 List<Order> 集合，映射到 User 实体的 orders 属性中。
@Select("select * from tb_user")
  @Results({
          @Result(column = "id",property = "id"),
          @Result(column = "username",property = "username"),
          @Result(column = "password",property = "password"),
          @Result(column = "id",property = "orders",javaType = List.class,//avaType = List.class声明 orders 属性的数据类型是 List（因为一个用户有多个订单，需要用集合存储）。作用：告诉 MyBatis，关联查询的结果需要封装成 List 集合（泛型由 ofType 隐式指定为 Order，这里省略了 ofType 但 MyBatis 会根据上下文推断）。
          many = @Many(select = "com.example.personblog.mapper.OrderMapper.findByUid")
          )//many = @Many(...)：表示一对多的关系,@Many专门用于配置一对多关系
          /*select =指定关联查询的方法，这里是 OrderMapper 中的 findByUid 方法（全限定名）。
          作用：当查询用户时，MyBatis 会自动调用 OrderMapper.findByUid(用户id) 方法，传入 column = "id" 对应的用户 id，查询该用户的所有订单。*/
  })
/*
1. 逐部分拆解含义
List<User>：这是方法的返回值类型，表示该方法执行后会返回一个「User对象的集合」：
List 说明返回的是多个数据（因为要查询 “所有用户”）；
<User> 说明集合中每个元素都是 User 类型的对象（每个对象包含用户自身信息 + 关联的订单列表）。
selectAllUserAndOrders：这是方法名，是自定义的标识符，通常根据功能命名（这里 “selectAllUserAndOrders” 直译为 “查询所有用户及其订单”，清晰表达了方法的作用）。方法名可以任意定义（只要符合 Java 命名规范），但建议见名知意。
()：括号中没有参数，说明这是一个无参方法—— 调用时不需要传入任何参数，默认查询 “所有用户” 及其订单（对应 SQL select * from tb_user）。
 */
    List<User> selectAllUserAndOrders();

}
/*我对于一个用户查询该用户所有订单的理解,一对多查询:

一、先判断你的理解：核心逻辑正确，但有 1 个关键细节需修正
1. 正确的部分
一对多查询的核心关联逻辑没问题：通过用户的id作为参数，调用OrderMapper.findByUid()，匹配订单表的uid外键，查询该用户的所有订单，这个流程是对的。
关于 “uid是形式参数” 的理解方向正确：OrderMapper中findByUid(int uid)的uid确实是形式参数，作用是接收外部传入的值。
2. 需修正的细节
你说 “查询 id 为 1 的用户，调用selectAllUserAndOrders()方法，在 UserMapper 里查询到所有关于 id 为 1 用户的信息”—— 这个描述不准确。当前UserMapper中selectAllUserAndOrders()的 SQL 是select * from tb_user，它默认查询的是所有用户，而非 “指定 id=1 的用户”。
若想查询 “id 为 1 的用户及其订单”，需要修改 SQL 为select * from tb_user where id = #{id}，并给方法加参数int id；
你当前的代码逻辑是：查询所有用户，对每个用户都通过id关联查询其订单，最终返回 “所有用户 + 各自订单” 的列表。

二、关于参数的疑问：为什么传id给findByUid(uid)能生效？
你的核心困惑是 “传入的是用户id，但方法参数名是uid”，这里需要明确 3 个关键概念：
1. 形式参数的本质
OrderMapper中findByUid(int uid)的uid是形式参数（简称 “形参”），它的作用只是 “接收外部传入的值”，名称可以任意定义（比如叫userId、id都可以），不影响功能。例如，你把方法改成这样也能正常工作：
java
运行
// 形参名改为id，和传入的用户id名称一致，功能完全相同
@Select("select * from orders where uid=#{uid}")
List<Order> findByUid(int id);
2. 关键是 “SQL 中的占位符与形参的绑定”
真正起作用的是 SQL 语句中的#{uid}—— 它会绑定到方法的形参上（无论形参叫什么名字，只要方法有且仅有一个形参，MyBatis 会自动将形参值赋给#{xxx}）。
你的代码中，#{uid}接收的是形参uid的值，而这个形参的值来自UserMapper传入的 “用户id”；
最终 SQL 执行时，会把 “用户id” 替换成#{uid}，变成select * from orders where uid=用户id，从而匹配订单表的外键uid。
3. 形参名与字段名的关系
形参名uid和订单表的uid列名没有强制关联，只是为了代码可读性，建议让形参名和 SQL 中用到的字段名保持一致。比如你也可以这样写（不推荐，可读性差，但功能正常）：
java
运行
// 形参名随便写，只要SQL占位符能拿到值
@Select("select * from orders where uid=#{abc}")
List<Order> findByUid(int abc);
 */



